<?php
/**
 *
 *
 *
 */
abstract class Yz_Form_Element_Abstract
    extends Yz_Object
    implements Yz_Form_Element_Interface
{

    protected $form;
    protected $name;
    protected $exception;
    protected $value = "";
    protected $element;
    protected $cssClass;


    /**
     *  @param Yz_Form_Interface the form the element belongs to
     *  @param Traversable elements: [name: params]
     *      Params are passed to element constructor
     *  @param Yz_Class $element
     */
    public function __construct(
        Yz_Form_Interface $form,
        $name,
        Yz_Class $element
        )
    {
        debug();
        $this->name = Yz_String::testNotEmpty($name);
        $this->element = $element;
        $this->form = $form;
        return;
    }

    /**
     *  Getter: x = $element->name
     *
     */
    final public function getName()
    {
        return $this->name;
    }

    /**
     *  Getter: x = $element->cssClass
     *
     */
    public function getCSSClass()
    {
        $css = 'yz-element-' . $this->shortClassName();
        if (null !== $this->cssClass) {
            $css .= ' ' . $this->cssClass;
        }
        return $css;
    }

    /**
     *  Getter: x = $element->value
     *
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     *  Setter: $element->value = x
     *
     */
    public function setValue($value)
    {
        $this->value = $value;
        return $this;
    }

    /**
     *  @param array $values
     *  @return chainable
     */
    public function findValue(Yz_Class $values)
    {
        $name = $this->name;
        if ($values->offsetExists($name)) {
            $this->setValue($values[$name]);
        }
        return $this;
    }

    /**
     *
     */
    public function render(Yz_Template_Interface $template)
    {
        $class = $this->getCSSClass();
        $o = <<<html
            <input type="text" name="{$this->name}" value="{$this->value}" class="{$class}" />\n
html;
        return $o;
    }

    /**
     *  @return this
     *  @throw Yz_Form_Element_Exception
     */
    public function parse(Yz_Hash $values)
    {
        debug("Element '$this->name'");
        if ($values->offsetExists($this->name)) {
            $this->value = $values[$this->name];
        }
        return $this;
    }


    /**
     *  Getter: x = $element->errorCode
     *
     */
    final public function getException()
    {
        return $this->exception;
    }

    /**
     *  @return name/title
     */
    final public function __toString()
    {
        return $this->name;
    }


    /**
     *
     *
     */
    protected function allowEmpty()
    {
        debug();
        return (! empty($this->element['allowEmpty']));
    }


}
